#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stropts.h>
#include<linux/fb.h>
#include <sys/mman.h>
#include<math.h>

#define LCD "/dev/ubuntu_lcd"
typedef unsigned int* lcd;
typedef unsigned int uint;
typedef unsigned char uch;

int size=800*480*4;
int lcdfd=-1;

lcd open_lcd(){
    lcdfd = open(LCD,O_RDWR);
    if(-1 == lcdfd){
        perror("open err");
        return NULL;
    }
    printf("设备打开成功\n");


    lcd p=mmap(NULL,size,PROT_READ | PROT_WRITE,MAP_SHARED,lcdfd,0);
    if(MAP_FAILED == p){
        perror("映射内存失败");
        return NULL;
    }

    printf("映射成功\n");
    return p;
}

int close_lcd(lcd p){

    int ret = munmap(p,size);
    if(-1 == ret){
        perror("解除映射失败");
    }
    printf("解除映射成功\n");
    ret = close(lcdfd);
    if(-1 == ret){
        perror("关闭设备失败\n");
        return -1;
    }
    printf("设备已关闭\n");
    return 0;

}


unsigned int RGB(uint r,uint g,uint b){

    uint rgb=(r<<16)|(g<<8)|b;

    return rgb;
}

void print(int x,int y,lcd p,uch* bmpbuf,uint* lcdbuf,int bmp_h,int bmp_w){

    for(int i =0;i<bmp_h*bmp_w;i++){
        lcdbuf[i] = (bmpbuf[i*3+0]<<0) | (bmpbuf[i*3+1]<<8) | (bmpbuf[i*3+2]<<16);
    }
    for(int i=y;i< bmp_h+y;i++){
        for(int j=x;j<bmp_w+x;j++){
            if( (j+i*800) >(800*480)){
                
                return;
            }
            p[j+i*800]=lcdbuf[(j-x)+(bmp_h-(i-y)-1)*bmp_w];
        }
    }

}


int main(int argc,const char* argv[]){

    if(argc != 2){
        return -1;
    }
    int bmpfd = open(argv[1],O_RDONLY);
    if(bmpfd == -1){
        perror("open err");
        return -1;
    }
    
    lcd p=open_lcd();

    uch info[54]={0};
    read(bmpfd,info,54);

    printf("文件标识:%c%c\n",info[0],info[1]);

    uint fsize = (info[5]<< 24) | (info[4]<<16) | (info[3]<<8) | (info[2]<<0);
    printf("文件总大小:%d\n",fsize);

    uint bmp_w=(info[21]<< 24) | (info[20]<<16) | (info[19]<<8) | (info[18]<<0);
    uint bmp_h=(info[25]<< 24) | (info[24]<<16) | (info[23]<<8) | (info[22]<<0);
    printf("宽:%d 高:%d \n",bmp_w,bmp_h);


    uch* bmpbuf = (uch*)malloc(bmp_h*bmp_w*3);
    if(bmpbuf == NULL){
        printf("bmpbuf err\n");
        return -1;
    }
    read(bmpfd,bmpbuf,bmp_h*bmp_w*3);

    uint* lcdbuf =(uint*)malloc(bmp_h*bmp_w*sizeof(uint));
    if(lcdbuf == NULL){
        printf("lcdbuf err\n");
        return -1;
    }


    print(400,480,p,bmpbuf,lcdbuf,bmp_h,bmp_w);
    // int x=400,y=240;
    // for(int i =0;i<bmp_h*bmp_w;i++){
    //     lcdbuf[i] = (bmpbuf[i*3+0]<<0) | (bmpbuf[i*3+1]<<8) | (bmpbuf[i*3+2]<<16);
    // }
    // for(int i=y;i< bmp_h+y;i++){
    //     for(int j=x;j<bmp_w+x;j++){
    //         p[j+i*800]=lcdbuf[(j-x)+(bmp_h-(i-y)-1)*bmp_w];
    //     }
    // }

    close_lcd(p);
    free(bmpbuf);
    free(lcdbuf);
    bmpbuf=NULL;
    lcdbuf=NULL;
    int ret=close(bmpfd);
    if(-1 == ret){
        printf("err\n");
        return -1;
    }
    return 0;

}